package org.example.executor.resultset;

import org.example.executor.Executor;
import org.example.mapping.BoundSql;
import org.example.mapping.MappedStatement;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: luyg
 * @Date: 2024/12/03/22:33
 * @Description:
 */
public class DefaultResultSetHandler implements ResultSetHandler{
    private final BoundSql boundSql;
    public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, BoundSql boundSql) {
        this.boundSql = boundSql;
    }
    @Override
    public <E> List<E> handleResultSets(Statement statement) throws SQLException {
        ResultSet resultSet = statement.getResultSet();
        try {
            return resultSet2Obj(resultSet,Class.forName(boundSql.getResultType()));
        }catch (ClassNotFoundException e){
            e.printStackTrace();
            return null;
        }
    }

    private <T> List<T> resultSet2Obj(ResultSet resultSet, Class<?> clazz) {
        List<T> result = new ArrayList<>();
        try {
            //获取字段信息
            ResultSetMetaData metaData = resultSet.getMetaData();
            //获取字段个数
            int columnCount = metaData.getColumnCount();
            //遍历查出来的行
            while (resultSet.next()){
                T obj = (T) clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    Object value = resultSet.getObject(i);
                    String columnName = metaData.getColumnName(i);
                    String setMethod="set"+columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
                    Method method;
                    if(value instanceof Timestamp){
                        method=clazz.getMethod(setMethod,Date.class);
                    }else {
                        method=clazz.getMethod(setMethod,value.getClass());
                    }
                    method.invoke(obj,value);
                }
                result.add(obj);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
}
